package com.shj.em.biz.report.service;

import com.shj.em.base.exception.BizException;
import com.shj.em.base.exception.EmCodeMsg;
import com.shj.em.biz.Constants;
import com.shj.em.biz.hr.entity.Dept;
import com.shj.em.biz.hr.entity.Emp;
import com.shj.em.biz.hr.service.DeptService;
import com.shj.em.biz.hr.service.EmpService;
import com.shj.em.biz.sell.entity.Ratio;
import com.shj.em.biz.sell.entity.Target;
import com.shj.em.biz.sell.service.RatioService;
import com.shj.em.biz.sell.service.TargetService;
import com.shj.em.biz.sell.entity.Order;
import com.shj.em.biz.sell.service.OrderService;
import com.shj.em.biz.prod.entity.Effort;
import com.shj.em.biz.prod.entity.MachineEffort;
import com.shj.em.biz.prod.service.EffortService;
import com.shj.em.biz.prod.service.MachineEffortService;
import com.shj.em.biz.report.dto.*;
import com.shj.em.biz.sys.entity.*;
import com.shj.em.biz.hr.mapper.DeptMapper;
import com.shj.em.biz.sys.service.*;
import com.shj.em.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

@Slf4j
@Service
public class ReportServiceImpl implements ReportService {
    @Autowired
    EmpService empService;

    @Autowired
    EffortService effortService;

    @Autowired
    OrderService orderService;

    @Autowired
    EmpRankService empRankService;

    @Autowired
    RankAmountService rankAmountService;

    @Autowired
    DeptService deptService;

    @Autowired
    TargetService targetService;

    @Autowired
    RatioService ratioService;

    @Autowired
    MachineEffortService machineEffortService;

    @Autowired
    DeptMapper deptMapper;

    public String validateConfigForGrowRatioReport(int year){
        Target target = targetService.getTargetByYear(year);
        if(target == null){
            return "请先设置" + year + "年的销售目标";
        }
        return null;
    }

    public List<EmpEffortsDTO> getEmpEffortsStat(int year){
        List<EmpEffortsDTO> empEffortsList = empService.findAllProdGroupTwoEmps();

        //key: empId, value: 每个月的总工时
        initTwelveMonth(empEffortsList);

        Map<Long, BigDecimal> orderUnitAmounts = getOrderUnitAmount(year);

        List<Effort> empEffortInYear = effortService.getEmpEffortInYear(year);

        Map<Long,List<EmpRank>> empRankMap = empRankService.findAllEmpRanks();

        //获得各个组别的工时权重
        Map<Long, BigDecimal> deptWeights = getDeptWeight();

        // 获得二部已经花费工时的订单，如果订单还是未完成的状态，则
        // 使用员工对应的上下限金额的中间值作为单位金额
        List<Order> allOrders = orderService.findHasWorkHourOrdersInYear(year);

        // rank 对应的金额
        Map<String, List<RankAmount>> rankAmountMap = rankAmountService.findAllRankAmountsInYear(year);

        if(rankAmountMap.size() == 0){
            throw new BizException(EmCodeMsg.RANK_AMOUNT_NOT_SET);
        }

        Long orderId = null;
        Long empId = null;
        EmpEffortsDTO ee = null;
        EffortStatDTO stat = null;

        for(Effort effort : empEffortInYear){
            empId = effort.getEmpId();
            ee = findEmpEfforts(empEffortsList, empId);
            int month = effort.getMonth();
            stat = ee.getStats().get(month - 1); //得到这个月的统计对象
            BigDecimal orderUnit = orderUnitAmounts.get(effort.getOrderId());

            //增加这个月的总工时
            stat.addTotalEffort(effort.getWorkHour());

            // 得到员工对应的等级和上下限
            RankAmount rankAmount = getEmpRankOfWorkDt(empId, effort.getWorkDt(), empRankMap, rankAmountMap);
            if(rankAmount == null){
                Emp emp = empService.selectById(empId);
                throw new BizException(emp.getEmpName() + "未设置等级。");
            }

            boolean isOrderFinished = isOrderFinished(allOrders, effort.getOrderId());

            //设置调整前的工作效率
            if(isOrderFinished){
                stat.addXiaoLvBefore(orderUnit.multiply(effort.getWorkHour())
                            .multiply(deptWeights.get(effort.getDeptId()))
                            .setScale(2, RoundingMode.HALF_UP));
            }else{
                stat.addXiaoLvBefore(rankAmount.getMin().add(rankAmount.getMax())
                        .divide(Constants.half)
                        .multiply(effort.getWorkHour())
                        .multiply(deptWeights.get(effort.getDeptId()))
                        .setScale(2, RoundingMode.HALF_UP));
            }

            //设置调整后的工作效率
            BigDecimal adjust = getEmpAdjustUnitEffort(rankAmount, orderUnit, isOrderFinished);
            stat.addXiaoLvAfter(adjust.multiply(effort.getWorkHour())
                    .multiply(deptWeights.get(effort.getDeptId()))
                    .setScale(2, RoundingMode.HALF_UP));
        }

        return empEffortsList;
    }

    //获得各个组别的工时权重
    private Map<Long, BigDecimal> getDeptWeight(){
        List<Dept> depts = deptMapper.findProdGrpTwoWithEffortWeight(CdService.CD_TYPE_EFFORT_WEIGHTS);

        Map<Long, BigDecimal> map = new HashMap<>();
        for(Dept dept : depts){
            String weight = dept.getWeightValue();
            if(StringUtils.isBlank(weight)){
                map.put(dept.getId(), new BigDecimal(1));
            }else {
                map.put(dept.getId(), new BigDecimal(weight));
            }
        }
        return map;
    }

    private boolean isOrderFinished(List<Order> allOrders, Long orderId){
        for(Order order : allOrders){
            if(order.getId().longValue() == orderId.longValue()){
                return order.isAllProdFinished();
            }
        }
        // 程序应该不会走到这里
        log.error("订单（" + orderId + "）未找到相应工时");
        throw new BizException("工时数据异常");
    }

    public List<GroupEffortDTO> getGroupEffortsStat(int year){
        List<Dept> depts = deptService.findAllProdGroupTwoDepts();
        List<GroupEffortDTO> groupEffortDTOList = initGroupEffortStat(depts);

        Map<Long, BigDecimal> orderUnitAmounts = getOrderUnitAmount(year);

        List<Effort> empEffortInYear = effortService.getEmpEffortInYear(year);

        Map<Long,List<EmpRank>> empRankMap = empRankService.findAllEmpRanks();
        Map<String, List<RankAmount>> rankAmountMap = rankAmountService.findAllRankAmountsInYear(year);

        //获得各个组别的工时权重
        Map<Long, BigDecimal> deptWeights = getDeptWeight();

        // 获得二部已经花费工时的订单，如果订单还是未完成的状态，则
        // 使用员工对应的上下限金额的中间值作为单位金额
        List<Order> allOrders = orderService.findHasWorkHourOrdersInYear(year);

        GroupEffortDTO groupEffortDTO = null;
        EffortStatDTO statDTO = null;
        for(Effort effort : empEffortInYear){
            Long deptId = effort.getDeptId();
            groupEffortDTO = findGroupEffortDTO(groupEffortDTOList, deptId);

            int month = effort.getMonth();
            statDTO = groupEffortDTO.getStats().get(month - 1); //得到这个月的统计对象
            BigDecimal orderUnit = orderUnitAmounts.get(effort.getOrderId());

            //增加这个月的总工时
            statDTO.addTotalEffort(effort.getWorkHour());

            // 得到员工对应的等级和上下限
            RankAmount rankAmount = getEmpRankOfWorkDt(effort.getEmpId(), effort.getWorkDt(), empRankMap, rankAmountMap);
            if(rankAmount == null){
                Emp emp = empService.selectById(effort.getEmpId());
                throw new BizException(emp.getEmpName() + "未设置等级。");
            }

            boolean isOrderFinished = isOrderFinished(allOrders, effort.getOrderId());

            //设置调整前的工作效率
            statDTO.addXiaoLvBefore(orderUnit.multiply(effort.getWorkHour())
                    .multiply(deptWeights.get(effort.getDeptId()))
                    .setScale(2, RoundingMode.HALF_UP));

            BigDecimal adjust = getEmpAdjustUnitEffort(rankAmount, orderUnit,
                                                        isOrderFinished);

            statDTO.addXiaoLvAfter(adjust.multiply(effort.getWorkHour())
                    .multiply(deptWeights.get(effort.getDeptId()))
                    .setScale(2, RoundingMode.HALF_UP));
        }

        return groupEffortDTOList;
    }

    public GrowRatioDTO getGrowRatio(int year){
        GrowRatioDTO growRatioDTO = new GrowRatioDTO();

        //当前年目标值
        List<Integer> currentTarget = getCurrentYearTarget(year);
        growRatioDTO.setCurrentYearTarget(currentTarget);

        //去年每月的销售額
        List<BigDecimal> amountPerMonthInLastYear = orderService.getAmountPerMonthInYear(year-1);
        growRatioDTO.setLastYearActual(amountPerMonthInLastYear);

        //当前年每月的销售
        List<BigDecimal> amountPerMonthInCurrentYear = orderService.getAmountPerMonthInYear(year);
        growRatioDTO.setCurrentYearActual(amountPerMonthInCurrentYear);

        //当前年累计销售目标
        growRatioDTO.setCurrentYearAccumTarget(getAccumTarget(currentTarget));

        //去年每月累计销售額
        growRatioDTO.setLastYearAccumActual(getAccumActual(amountPerMonthInLastYear));

        //当前年每月累计销售額
        growRatioDTO.setCurrentYearAccumActual(getAccumActual(amountPerMonthInCurrentYear));

        growRatioDTO.convert();// 转化成以万元为单位

        //完成率
        growRatioDTO.calcFinishRate();
        return growRatioDTO;
    }

    public ReturnRatioDTO genReturnRatioDTO(int year){
        ReturnRatioDTO ratioDTO = new ReturnRatioDTO();
        // 每月应收
        List<BigDecimal> shouldAmounts = orderService.getShouldReturnPerMonthInYear(year);
        ratioDTO.setShouldAmounts(shouldAmounts);

        //每月实收
        List<BigDecimal> returnAmounts = orderService.getReturnAmountPerMonthInYear(year);
        ratioDTO.setActualReturn(returnAmounts);

        //目标回款率
        List<Integer> ratios = getCurrentYearTargetRatio(year);
        ratioDTO.setTargetRatio(ratios);

        ratioDTO.convert();
        ratioDTO.calculate();

        return ratioDTO;
    }

    private List<Integer> getCurrentYearTargetRatio(int year){
        List<Integer> list = new ArrayList<>();
        Ratio ratio = ratioService.getRatioByYear(year);
        list.add(ratio.getJan());
        list.add(ratio.getFeb());
        list.add(ratio.getMar());
        list.add(ratio.getApr());
        list.add(ratio.getMay());
        list.add(ratio.getJun());
        list.add(ratio.getJul());
        list.add(ratio.getAug());
        list.add(ratio.getSep());
        list.add(ratio.getOct());
        list.add(ratio.getNov());
        list.add(ratio.getDece());
        return list;
    }

    private List<Integer> getCurrentYearTarget(int year){
        List<Integer> list = new ArrayList<>();
        Target target = targetService.getTargetByYear(year);
        list.add(target.getJan());
        list.add(target.getFeb());
        list.add(target.getMar());
        list.add(target.getApr());
        list.add(target.getMay());
        list.add(target.getJun());
        list.add(target.getJul());
        list.add(target.getAug());
        list.add(target.getSep());
        list.add(target.getOct());
        list.add(target.getNov());
        list.add(target.getDece());
        return list;
    }


    private List<Integer> getAccumTarget(List<Integer> perMonth){
        List<Integer> accumMonth = new ArrayList<>();
        for(int i = 0 ; i < perMonth.size(); i++){
            if(i == 0){
                accumMonth.add(perMonth.get(i));
            }else{
                accumMonth.add(accumMonth.get(i-1) + perMonth.get(i));
            }
        }
        return accumMonth;
    }

    private List<BigDecimal> getAccumActual(List<BigDecimal> perMonth){
        List<BigDecimal> accumMonth = new ArrayList<>();
        for(int i = 0 ; i < perMonth.size(); i++){
            if(i == 0){
                accumMonth.add(perMonth.get(i));
            }else{
                accumMonth.add(accumMonth.get(i-1).add(perMonth.get(i)));
            }
        }
        return accumMonth;
    }

    //单位订单金额
    private Map<Long, BigDecimal> getOrderUnitAmount(int year){
        //key: orderId,  value: 订单总工时
        Map<Long, BigDecimal> orderTotalEffort = effortService.getOrderTotalEffort(year);

        //key: orderId,  value: 订单总金额（去除外发金额后）
        Map<Long, BigDecimal> orderAmountMap = orderService.getOrderAmountInYear(year);

        //为了节省内存，直接使用orderTotalEffort 作为订单单位金额
        BigDecimal totalAmount = null;
        BigDecimal totalEffort = null;
        for(Long orderId : orderTotalEffort.keySet()){
            totalAmount = orderAmountMap.get(orderId);
            totalEffort = orderTotalEffort.get(orderId);
            orderTotalEffort.put(orderId, totalAmount.divide(totalEffort, 2, RoundingMode.HALF_UP));
        }
        return orderTotalEffort;
    }

    private RankAmount getEmpRankOfWorkDt(Long empId, Date workDt, Map<Long,List<EmpRank>> empRankMap,
                                       Map<String, List<RankAmount>> rankAmountMap){
        List<EmpRank> empRankList = empRankMap.get(empId);
        if(empRankList == null || empRankList.isEmpty()){
            log.error("员工(" + empId +")没有设置等级");
            return null;
        }

        String rank = null;
        //获取这个工作日期的等级
        for(int i = 0; i < empRankList.size(); i++){
            if(rank != null){
                break;
            }
            //员工当前工作日期时候的等级，肯定晚于定义其等级的时间。
            boolean afterDefineDt = workDt.compareTo(empRankList.get(i).getDefineDt()) > -1;
            if(afterDefineDt){
                if(i == empRankList.size() - 1){//如果没有下一条了
                    rank = empRankList.get(i).getRank();
                }else{
                    //当前工作日期早于下一个定义其等级的时间，当前等级即为员工的等级
                    if(workDt.compareTo(empRankList.get(i+1).getDefineDt()) < 0){
                        rank = empRankList.get(i).getRank();
                    }
                }
            }
        }

        if(rank == null){ // 未设置员工的等级
            log.error("员工(" + empId +")未设置等级");
            return null;
        }

        //获取这个等级的最大最小效率
        RankAmount rankAmount = null;
        RankAmount ra = null;

        // 每个等级对应上下限金额会调整，所以一个等级会有多个记录
        List<RankAmount> rankAmountList = rankAmountMap.get(rank);
        if(rankAmountList == null || rankAmountList.isEmpty()){
            log.error("等级(" + rank +")没有设置上下限金额");
            return null;
        }

        for(int i = 0; i < rankAmountList.size(); i++){
            if(rankAmount != null){
                break;
            }
            ra = rankAmountList.get(i);
            if(ra.getRank().equals(rank)){
                if(workDt.compareTo(ra.getDefineDt()) > -1){ // 工作日期在定义等级金额的日期之后
                    if(i == rankAmountList.size() - 1 ||
                            workDt.compareTo(rankAmountList.get(i+1).getDefineDt()) < 0){
                        rankAmount = ra;
                    }
                }
            }
        }
        if(rankAmount == null){
            log.warn("没找到员工对应的等级");
            return null;
        }

        return rankAmount;
    }

    // 获得员工的最小和最大单位效率
    private BigDecimal getEmpAdjustUnitEffort(RankAmount rankAmount, BigDecimal orderUnitAmount,
                                               boolean isOrderFinished){

        if(isOrderFinished){
            if (orderUnitAmount.compareTo(rankAmount.getMin()) <= 0) {
                return rankAmount.getMin();
            } else if (orderUnitAmount.compareTo(rankAmount.getMax()) >= 0) {
                return rankAmount.getMax();
            } else {
                return orderUnitAmount;
            }
        }else{
            return rankAmount.getMin().add(rankAmount.getMax()).divide(Constants.half, 2, RoundingMode.HALF_UP);
        }

    }

    private List<GroupEffortDTO> initGroupEffortStat(List<Dept> depts){
        List<GroupEffortDTO> groupEffortDTOList = new ArrayList<>();
        GroupEffortDTO groupEffortDTO = null;
        for(Dept dept : depts){
            groupEffortDTO = new GroupEffortDTO();
            groupEffortDTO.setDeptId(dept.getId());
            groupEffortDTO.setDeptName(dept.getDeptName());
            groupEffortDTO.setStats(initTwelveMonthStat());
            groupEffortDTOList.add(groupEffortDTO);
        }
        return groupEffortDTOList;
    }

    private List<EffortStatDTO> initTwelveMonthStat(){
        List<EffortStatDTO> stats = new ArrayList<>();
        EffortStatDTO ees = null;
        for(int i = 0; i < 12; i++){//12 为一年的月数
            ees = new EffortStatDTO();
            stats.add(ees);
        }
        return stats;
    }

    private void initTwelveMonth(List<EmpEffortsDTO> empEffortsList){
        for(EmpEffortsDTO ee : empEffortsList){
            ee.setStats(initTwelveMonthStat());
        }
    }

    private GroupEffortDTO findGroupEffortDTO(List<GroupEffortDTO> effortDTOList, Long deptId){
        for(GroupEffortDTO dto : effortDTOList){
            if(deptId.equals(dto.getDeptId())){
                return dto;
            }
        }
        log.error("在groupEffortsList中找不到deptId("+ deptId+")");
        return null; // 应该不会出现这种情况
    }

    private EmpEffortsDTO findEmpEfforts(List<EmpEffortsDTO> empEffortsList, Long empId){
        for(EmpEffortsDTO ee : empEffortsList){
            if(ee.getEmpId().equals(empId)){
                return ee;
            }
        }
        log.error("在empEffortsList中找不到empId("+ empId+")");
        return null; // 应该不会出现这种情况
    }

    public FirstGrpEffortDTO getFirstGroupDayEffort(Date date){
        FirstGrpEffortDTO grpEffortDTO = getFirstGrpEmpNames();

        List<MachineEffort> machineEfforts = machineEffortService.findByDate(date);

        List<BigDecimal> empEfforts = new ArrayList<>();
        grpEffortDTO.setCurrentDayEfforts(empEfforts);
        if(machineEfforts == null || machineEfforts.isEmpty()){
            return grpEffortDTO;
        }

        Map<String, BigDecimal> empEffortsMap = new HashMap<>();
        BigDecimal singleEffort = null;
        for(MachineEffort me : machineEfforts){
            // 对于跨班的工件，计算时设成1
            int prodNum = me.getNum() == 0 ? 1 : me.getNum();
            singleEffort = me.getEstimateHour()
                    .multiply(me.getEffortPercent())
                    .multiply(new BigDecimal(prodNum));
            if(empEffortsMap.containsKey(me.getEmpName())){
                empEffortsMap.put(me.getEmpName(), empEffortsMap.get(me.getEmpName()).add(singleEffort));
            }else{
                empEffortsMap.put(me.getEmpName(), singleEffort);
            }
        }

        // 计算员工效率，需要与上面的员工列表顺序一致
        for(String empName : grpEffortDTO.getEmps()){
            empEfforts.add(empEffortsMap.getOrDefault(empName, Constants.zero)
                    .multiply(Constants.hundred).divide(Constants.totalEffortOneDay, 2, RoundingMode.HALF_UP));
        }

        return grpEffortDTO;
    }

    private FirstGrpEffortDTO getFirstGrpEmpNames(){
        FirstGrpEffortDTO grpEffortDTO = new FirstGrpEffortDTO();
        //获得所有生产一部的员工
        List<EmpEffortsDTO> emps = empService.findAllProdGroupOneEmps();
        if(emps == null || emps.isEmpty()){
            throw new BizException(EmCodeMsg.EMP_NOT_FOUND);
        }

        //获取员工名字
        List<String> empNames = new ArrayList<>();
        for(EmpEffortsDTO empEffortsDTO : emps){
            empNames.add(empEffortsDTO.getEmpName());
        }
        grpEffortDTO.setEmps(empNames);
        return grpEffortDTO;
    }

    public FirstGrpEffortDTO getFirstGroupWeekEffort(Date weekFrom, Date weekTo){
        FirstGrpEffortDTO grpEffortDTO = getFirstGrpEmpNames();

        //获得这一周的总的工时
        List<MachineEffort> efforts = machineEffortService.findWeekEffort(weekFrom, weekTo);

        // 获是这一周的工作天数
        //TODO 暂时只能粗略估算，如果只是请半天假，则也一天，效率偏低
        List<MachineEffort> empWorkDays = machineEffortService.findWorkDaysInWeek(weekFrom, weekTo);

        List<BigDecimal> empEfforts = new ArrayList<>();
        grpEffortDTO.setCurrentDayEfforts(empEfforts);

        for(String empName : grpEffortDTO.getEmps()){
            Optional<BigDecimal> effort = findEffortOfEmp(empName, efforts);
            if(effort.isPresent()){
                int workDays = findWorkDaysOfEmp(empName, empWorkDays);
                empEfforts.add(effort.get()
                        .multiply(Constants.hundred)
                        .divide(Constants.totalEffortOneDay.multiply(new BigDecimal(workDays)), 2, RoundingMode.HALF_UP));
            }else{
                empEfforts.add(Constants.zero);
            }
        }

        return grpEffortDTO;
    }

    public FirstGrpEffortDTO getFirstGroupMonthEffort(int month){
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.MONTH, month - 1);
        cal.set(Calendar.DAY_OF_MONTH, 1);
        Date from = cal.getTime();

        cal.set(Calendar.MONTH, month); //设成下个月
        cal.add(Calendar.DATE, -1); // 设成下个月的前一天，即当前月月底

        Date to = cal.getTime();

        return getFirstGroupWeekEffort(from, to);
    }

    private Optional<BigDecimal> findEffortOfEmp(String empName, List<MachineEffort> efforts){
        for(MachineEffort me : efforts){
            if(empName.equals(me.getEmpName())){
                return Optional.of(me.getWorkHour());
            }
        }
        return Optional.empty();
    }

    private int findWorkDaysOfEmp(String empName, List<MachineEffort> empWorkDays){
        for(MachineEffort me : empWorkDays){
            if(empName.equals(me.getEmpName())){
                return me.getWorkDays();
            }
        }
        return Integer.MAX_VALUE; //不可能跑到这一行
    }

    public DeviceUsageDTO getDayDeviceUsage(Date date){
        DeviceUsageDTO deviceUsageDTO = new DeviceUsageDTO();
        deviceUsageDTO.init();
        List<MachineEffort> list = machineEffortService.findOneDayMachineEffort(date);
        // 理论利用率为： 理论时间/24小时
        // 实际利用率为： 实际使用时间/24小时
        for(MachineEffort me : list){
            deviceUsageDTO.getMachineNos().add(me.getMachineNo() + "#");
            deviceUsageDTO.getEstimates().add(me.getEstimateHour().multiply(Constants.hundred)
                    .divide(Constants.oneDay, 2, RoundingMode.HALF_UP));
            deviceUsageDTO.getActuals().add(me.getWorkHour().multiply(Constants.hundred)
                    .divide(Constants.oneDay, 2, RoundingMode.HALF_UP));
        }
        return deviceUsageDTO;
    }

    public DeviceUsageDTO getWeekDeviceUsage(Date weekFrom, Date weekTo){
        DeviceUsageDTO deviceUsageDTO = new DeviceUsageDTO();
        deviceUsageDTO.init();
        List<MachineEffort> rangeUsage = machineEffortService.findRangeMachineEffort(weekFrom, weekTo);
        List<MachineEffort> workDays = machineEffortService.findMachineUsageDays(weekFrom, weekTo);

        for(MachineEffort me : rangeUsage){
            Integer days = null;
            for(MachineEffort tmp : workDays){
                if(me.getMachineNo().equals(tmp.getMachineNo())){
                    days = tmp.getWorkDays();
                }
            }
            if(days != null){
                BigDecimal total = Constants.oneDay.multiply(new BigDecimal(days));
                deviceUsageDTO.getMachineNos().add(me.getMachineNo() + "#");
                deviceUsageDTO.getEstimates().add(me.getEstimateHour().multiply(Constants.hundred)
                        .divide(total, 2, RoundingMode.HALF_UP));
                deviceUsageDTO.getActuals().add(me.getWorkHour().multiply(Constants.hundred)
                        .divide(total, 2, RoundingMode.HALF_UP));
            }

        }

        return deviceUsageDTO;
    }

    public DeviceUsageDTO getMonthDeviceUsage(int month){
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.MONTH, month - 1);
        cal.set(Calendar.DAY_OF_MONTH, 1);
        Date from = cal.getTime();

        cal.set(Calendar.MONTH, month); //设成下个月
        cal.add(Calendar.DATE, -1); // 设成下个月的前一天，即当前月月底

        Date to = cal.getTime();
        return getWeekDeviceUsage(from, to);
    }
}
